package com.xf.lastmall.controller;


import com.xf.lastmall.feign.PayServiceApi;
import com.xf.lastmall.moudle.dto.NewOrderRefundDto;
import com.xf.lastmall.moudle.enums.OrderCanRefund;
import com.xf.lastmall.moudle.enums.OrderPayStatus;
import com.xf.lastmall.moudle.enums.RefundApplyStatus;
import com.xf.lastmall.moudle.exception.OrderException;
import com.xf.lastmall.order.api.common.Response;
import com.xf.lastmall.order.api.dto.OnlineOrderDto;
import com.xf.lastmall.moudle.entity.OrderDetailEntity;
import com.xf.lastmall.moudle.entity.OrderMainEntity;
import com.xf.lastmall.moudle.entity.OrderRefundEntity;
import com.xf.lastmall.service.*;
import com.xf.lastmall.util.IdGenUtil;
import com.xf.lastmall.util.OrderNoGenUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.List;


@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {

    @Resource
    private OrderManageService orderManageService;
    @Resource
    private OrderMainService orderMainService;
    @Resource
    private OrderDetailService orderDetailService;
    @Resource
    private OrderRefundService orderRefundService;
    @Resource
    private OrderRefTool tool;
    @Resource
    private OrderNoGenUtil orderNoGenUtil;
    @Resource
    private PayServiceApi payServiceApi;


    /**
     * 创建订单 并 调用支付服务生成支付请求参数
     */
    @RequestMapping(value = "/", method = RequestMethod.POST)
    public Response<?> saveOrder(@RequestBody OnlineOrderDto orderDto) {
        OrderMainEntity orderMainEntity = this.convert2OrderEntity(orderDto);
        orderMainEntity.getOrderDetailEntityList().forEach(p -> {
            if (p.getConsumeWay() == null) {
                p.setConsumeWay(2);
            }
            if (p.getUsePeriod() == null) {
                p.setUsePeriod(510510);
            }
        });
        try {
            orderManageService.saveOrderInfo(orderMainEntity);
        } catch (Exception e) {
            log.error("保存订单出现异常 orderDto:{} e", orderDto, e);
            return new Response<>(Response.Status.FAILED, "下单出错");
        }
        return tool.toPay(orderMainEntity, orderDto.getPayType(), "");
    }


    /**
     * 查询订单 findOrderMainDetailByOrderNo
     *
     * @param orderNo
     * @return
     */
    @RequestMapping(value = "/main-detail-by-order-no", method = RequestMethod.GET)
    public Response<OrderMainEntity> findOrderMainDetailByOrderNo(@RequestParam("orderNo") String orderNo) {
        OrderMainEntity mainEntity = orderManageService.findOrderMainDetail(null, orderNo);
        return Response.success(mainEntity);
    }


    /**
     * 生成支付请求参数
     *
     * @param orderNo
     * @return
     */
    @RequestMapping(value = "/build-pay-req-params", method = RequestMethod.GET)
    public Response<?> buildPayReqParams(@RequestParam("orderNo") String orderNo, @RequestParam("payType") String payType) {
        OrderMainEntity orderMainEntity = orderMainService.findOrderMainEntityByOrderNo(orderNo);
        return tool.toPay(orderMainEntity, Integer.parseInt(payType), "");
    }


    /**
     * 退款单生成
     */
    @RequestMapping(value = "/refund", method = RequestMethod.POST)
    public Response<?> applyRefund(@RequestParam("orderSubNo") String orderNo,
                                   @RequestParam("userId") String userId,
                                   @RequestParam("refundReason") String refundReason,
                                   @RequestParam("platform") String platform,
                                   @RequestParam("refundType") String refundType,
                                   @RequestParam("openId") String openId,
                                   @RequestParam("numb") int numb) {
        log.info("申请退款请求参数orderNo:{},numb:{}", orderNo, numb);
        OrderMainEntity orderMainEntity = orderMainService.findOrderMainEntityByOrderNo(orderNo);
        OrderDetailEntity orderDetailEntity = orderDetailService.findAllSubOrderByOrderNo(orderNo).get(0);

        if (!OrderPayStatus.PAY_SUCCESS.getValue().equals(orderMainEntity.getStatus())) {
            return new Response<>(Response.Status.FAILED, "订单状态不正确不支持退款", null);
        }
        if (!orderMainEntity.getMemberId().equals(userId)) {
            return new Response<>(Response.Status.FAILED, "非本人订单，禁止操作", null);
        }
        if (OrderCanRefund.CAN_REFUND.getValue() != orderDetailEntity.getCanRefund()) {
            return new Response<>(Response.Status.FAILED, "该订单不支持退款", null);
        }

        OrderRefundEntity orderRefundEntity = new OrderRefundEntity();
        String batchNo = orderNoGenUtil.getNextBatchNo(orderMainEntity.getMallCode());
        orderRefundEntity.setBatchNo(batchNo);
        orderRefundEntity.setOrderSubNo(orderDetailEntity.getOrderSubNo());
        orderRefundEntity.setOrderNo(orderMainEntity.getOrderNo());
        orderRefundEntity.setId(IdGenUtil.getNextId());
        orderRefundEntity.setMallCode(orderMainEntity.getMallCode());
        orderRefundEntity.setMemberId(userId);
        orderRefundEntity.setChannel(orderMainEntity.getChannel());
        orderRefundEntity.setRefundType(refundType);
        orderRefundEntity.setMemberName(orderMainEntity.getMemberName());
        //前端不传默认退全部
        orderRefundEntity.setRefundNumb(numb < 0 ? orderDetailEntity.getQuality() : numb);
        orderRefundEntity.setRefundNo("T" + orderNoGenUtil.getNextOrderNo(orderMainEntity.getMallCode()));
        orderRefundEntity.setRefundReason(refundReason);
        orderRefundEntity.setCreateTime(new Date());
        orderRefundEntity.setStatus(RefundApplyStatus.REFUNDS_AUDIT_BEGIN.getValue());
        orderRefundEntity.setRefundAmount(orderDetailEntity.getSellPrice().multiply(new BigDecimal(orderRefundEntity.getRefundNumb())));


        //使用update数据库 判断是否有足够的数量可供退款 必须前置处理  否则可能导致退款金额大于该商品可退金额
        if (1 != orderDetailService.updateAndSaveDetailForRefund(orderDetailEntity.getOrderSubNo(), orderRefundEntity.getRefundNumb(), orderRefundEntity)) {
            return new Response<>(Response.Status.FAILED, "可供退款的数量不足", null);
        }
        return new Response<>(Collections.singletonMap("refundsNo", orderRefundEntity.getRefundNo()));
    }


    /**
     * 新订单取消
     */
    @RequestMapping(value = "/cancel", method = RequestMethod.POST)
    Response<?> cancelOrder(@RequestParam("orderNo") String orderNo, @RequestParam("memberId") String memberId) {
        OrderMainEntity orderMainEntity = orderMainService.findOrderMainEntityByOrderNo(orderNo);
        if (!memberId.equals(orderMainEntity.getMemberId())) {
            return new Response<>(Response.Status.FAILED, "非本人订单，禁止操作");
        }

        if (!OrderPayStatus.WAIT_BUY.getValue().equals(orderMainEntity.getStatus())) {
            return new Response<>(Response.Status.FAILED, "订单状态不合法，不允许操作");
        }

        //综合支付取消流程
        // todo
        Response response = payServiceApi.mixcOrderQuery(orderNo);
        //支付成功不允许取消订单
        if (response.isSuccess()) {
            throw new OrderException("订单支付成功,取消订单失败");
        }

        if (1 == orderMainService.updateOrderStatus(OrderPayStatus.ORDER_CANCEL.getValue(), OrderPayStatus.WAIT_BUY.getValue(), new Date(), orderNo)) {
            // todo: 订单成功取消的异步事件发送
            /*
            OrderMessageDto messageDto = new OrderMessageDto();
            messageDto.setType(3);
            messageDto.setOrderStatus(AdminOrderStatus.order_status_06.getValue());
            messageDto.setOrderNo(orderNo);
            messageDto.setNumb(orderMainEntity.getTotalQuantity());
            streamMessageSender.sendMessage(messageDto);*/
        }

        return new Response<>();
    }

    /**
     * 删除订单
     *
     * @param orderNo
     * @param memberId
     * @return
     */

    @RequestMapping("delete")
    Response deleteOrder(@RequestParam("orderNo") String orderNo, @RequestParam("memberId") String memberId) {

        OrderMainEntity orderMainEntity = orderMainService.findOrderMainEntityByOrderNo(orderNo);

        if (!memberId.equals(orderMainEntity.getMemberId())) {
            return new Response(Response.Status.FAILED, "非本人订单，禁止操作");
        }

        boolean flag = false;
        if (OrderPayStatus.WAIT_BUY.getValue().equals(orderMainEntity.getStatus())) {
        } else if (OrderPayStatus.PAY_SUCCESS.getValue().equals(orderMainEntity.getStatus())) {
            List<OrderDetailEntity> orderDetailEntityList = orderDetailService.findAllSubOrderByOrderNo(orderNo);
            OrderDetailEntity orderDetailEntity = orderDetailEntityList.get(0);
            if (orderDetailEntity.getQuality() - orderDetailEntity.getRefundQuality() - orderDetailEntity.getConsumeQuality() == 0) {
                flag = true;
            }

        } else if (OrderPayStatus.ORDER_CANCEL.getValue().equals(orderMainEntity.getStatus())) {
            flag = true;
        } else if (OrderPayStatus.ORDER_CLOSE.getValue().equals(orderMainEntity.getStatus())) {
            flag = true;
        }
        if (flag) {
            orderMainService.deleteOrder(orderNo);
            return new Response<>(Response.Status.SUCCESS, "删除成功");
        }
        return new Response<>(Response.Status.FAILED, "订单目前状态不支持删除");
    }


    /**
     * 取消退款
     *
     * @param orderNo
     * @param memberId
     * @return
     */
    @RequestMapping("cancel/refund")
    Response<String> cancelRefund(@RequestParam("orderNo") String orderNo, @RequestParam("memberId") String memberId) {
        log.info("取消退款參數cancel/refund order:{} memberId:{}", orderNo, memberId);

        NewOrderRefundDto refundDto = orderRefundService.findRefundDtoByOrderNo(orderNo);
        if (refundDto == null) {
            return new Response<>(Response.Status.FAILED, "订单状态有误，不允许操作");
        }


        if (!memberId.equals(refundDto.getMemberId())) {
            return new Response<>(Response.Status.FAILED, "非本人订单，禁止操作");
        }

        if (refundDto.getUseEndTime() != null && new Date().compareTo(refundDto.getUseEndTime()) > 0) {
            return new Response<>(Response.Status.FAILED, "商品已过核销时间，不可取消退款，预计将2-3工作日退款，请注意查收");
        }

        log.info("取消退款更改数据库操作  orderSubNo:{} refundNumb:{}", refundDto.getOrderSubNo(), refundDto.getRefundNumb());
        if (1 == orderManageService.updateOrderForCancelRefund(refundDto.getRefundsNo(), refundDto.getOrderSubNo(), refundDto.getRefundNumb())) {
//            OrderMessageDto messageDto = new OrderMessageDto();
//            messageDto.setType(3);
//            messageDto.setOrderStatus(AdminOrderStatus.order_status_02.getValue());
//            messageDto.setOrderNo(orderNo);
//            messageDto.setNumb(0);
//            streamMessageSender.sendMessage(messageDto);
            return new Response<>(OrderPayStatus.PAY_SUCCESS.getValue());
        }

        return new Response<>(Response.Status.FAILED.getCode(), "取消退款失败，请稍后再试~~");

    }

    /**
     * 主动查询支付结果
     *
     * @param orderNo
     * @param payType
     * @return
     */
    @RequestMapping("verify")
    Response<OrderDetailEntity> verufyResult(@RequestParam("orderNo") String orderNo, @RequestParam("payType") String payType) {
        OrderMainEntity orderMainEntity = orderMainService.findOrderMainEntityByOrderNo(orderNo);
        boolean flag = false;
        Response response = payServiceApi.mixcOrderQuery(orderNo);
        if (response.isSuccess()) {
            flag = true;
        }
        if (flag) {
            List<OrderDetailEntity> orderDetailEntityList = orderDetailService.findAllSubOrderByOrderNo(orderNo);
            //非购物车暂时只i有一种商品
            if (orderDetailEntityList != null && !orderDetailEntityList.isEmpty()) {
                return new Response(orderDetailEntityList.get((0)));
            }
        }

        return new Response(Response.Status.FAILED, "支付失败");
    }


    /**
     * 将请求参数转化为  下单对象
     */
    private OrderMainEntity convert2OrderEntity(OnlineOrderDto orderDto) {

        OrderMainEntity orderMainEntity = new OrderMainEntity();
        if (!tool.isSupportIpp(orderDto.getMallCode())) {
            orderMainEntity.setChannel("mixc");
        }
        orderMainEntity.setOrderNo(orderNoGenUtil.getNextOrderNo(orderDto.getMallCode()));
        orderMainEntity.setMallCode(orderDto.getMallCode());
        orderMainEntity.setMemberId(orderDto.getUserId());
        orderMainEntity.setMemberName(orderDto.getUserName());
        orderMainEntity.setOrderType(orderDto.getOrderType());
        orderMainEntity.setPayType(String.valueOf(orderDto.getPayType()));
        orderMainEntity.setId(IdGenUtil.getNextId());
        orderMainEntity.setSource(orderDto.getSource());
        orderMainEntity.setStatus(OrderPayStatus.WAIT_BUY.getValue());
        orderMainEntity.setCreateTime(new Date());
        orderMainEntity.setMemberMobile(orderDto.getMemberMoboile());
        orderMainEntity.setMerchantPhone(null);

        OrderDetailEntity orderDetailEntity = new OrderDetailEntity();
        orderDetailEntity.setCreateTime(new Date());
        orderDetailEntity.setId(IdGenUtil.getNextId());
        orderDetailEntity.setOrderNo(orderMainEntity.getOrderNo());
        orderDetailEntity.setOrderSubNo(orderNoGenUtil.getNextOrderSubNo(orderDto.getMallCode(), orderDto.getOrderType()));
        orderDetailEntity.setConsumeCode(orderDto.getConsumeCode());
        orderDetailEntity.setCommodityNo(orderDto.getCommodityNo());
        orderDetailEntity.setCommodityPicUrl(orderDto.getCommodityPicUrl());
        orderDetailEntity.setCommodityName(orderDto.getCommodityName());
        orderDetailEntity.setMarketPrice(orderDto.getMarketPrice());
        orderDetailEntity.setDiscount(orderDto.getDiscount());
        orderDetailEntity.setSellPrice(orderDto.getSellPrice());
        orderDetailEntity.setQuality(orderDto.getQuality());
        orderDetailEntity.setServiceScope(Integer.parseInt(orderDto.getServiceScope()));
        orderDetailEntity.setServiceMerchantCode(orderDto.getServiceMerchantCode());
        orderDetailEntity.setServiceMerchantName(orderDto.getServiceMerchantName());
        orderDetailEntity.setCanConsume(orderDto.getCanConsume());
        orderDetailEntity.setCanRefund(orderDto.getCanRefund());
        orderDetailEntity.setUseBeginTime(orderDto.getUseBeginTime());
        orderDetailEntity.setUseEndTime(orderDto.getUseEndTime());
        orderDetailEntity.setCommodityProperty(orderDto.getCommodityPropertyList().toString());

        //创意活动的券id和名称默认为null
        orderDetailEntity.setCouponId(null);
        orderDetailEntity.setCouponName(null);
        orderDetailEntity.setExternalSaleChannel(null);

        if (orderDetailEntity.getServiceScope() == 1) {
            orderMainEntity.setServiceMerchantCode(orderDetailEntity.getServiceMerchantCode());
        }
        orderMainEntity.setTotalPrice(orderDetailEntity.getSellPrice().multiply(new BigDecimal(orderDetailEntity.getQuality())));
        orderMainEntity.setGoodsPrice(orderDetailEntity.getMarketPrice().multiply(new BigDecimal(orderDetailEntity.getQuality())));
        orderMainEntity.setTotalQuantity(orderDetailEntity.getQuality());
        orderMainEntity.setOrderSubject(orderDto.getMallCode() + "-" + orderDetailEntity.getCommodityName());
        orderMainEntity.setOrderDetailEntityList(Collections.singletonList(orderDetailEntity));

        return orderMainEntity;

    }

}